﻿using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VisionCloud.Core.Model.Enums;
using VisionCloud.Core.Model.Sys;
using VisionCloud.Domain.Common;
using VisionCloud.Domain.DtoModel.Schedule.RobotInfo;
using VisionCloud.Domain.Repository.Interface.Sys;

namespace VisionCloud.Service.Schedule
{
    public class RobotInfoService
    {
        public ISysDeviceRepository RobotInfoDao { set; get; }
        public ISysUserRepository SysUserRepository { set; get; }
        public IMapper Mapper { set; get; }

        public RobotInfoListDto GetRobotInfoList(PageRequest request)
        {
            var total = RobotInfoDao.GetAll().Where(x => x.IsActive == true && x.IsDeleted == false)
                .Where(x => string.IsNullOrEmpty(request.Keywords) || x.DeviceNO.Contains(request.Keywords)).Count();

            var result = RobotInfoDao.GetAll().Where(x => x.IsActive == true && x.IsDeleted == false)
                .Where(x => string.IsNullOrEmpty(request.Keywords) || x.DeviceNO.Contains(request.Keywords))
                .Skip(request.Page * request.PageSize - request.PageSize)
                .Take(request.PageSize)
                .OrderByDescending(x => x.CreatedDate)
                .ToList();

            List<RobotInfoDto> list = Mapper.Map<List<SysDevice>, List<RobotInfoDto>>(result);
            return new RobotInfoListDto
            {
                List = list,
                Total = total
            };
        }

        public List<RobotLocaltionDto> GetLocaltionList()
        {
            var result = RobotInfoDao.GetAll()
                .Where(x => x.IsDeleted == false && x.IsActive == true)
                .Select(x => new RobotLocaltionDto
                {
                    Id = x.DeviceGuid,
                    Status = x.AvailableStatus,
                    Longitude = x.Longitude,
                    Latitude = x.Latitude
                }).ToList();
            return result;
        }

        public RobotScheduleDto Schedule(RobotScheduleRqDto request)
        {
            var robotList = RobotInfoDao.GetAll().Where(x => x.AvailableStatus == (int)DeviceAvailableStatusEnum.闲置)
                .Where(x => x.IsActive == true && x.IsDeleted == false)
                .OrderBy(x => Math.Sqrt(Math.Abs(Math.Pow(x.Longitude - request.Longitude, 2.0)) +
                Math.Abs(Math.Pow(x.Latitude - request.Latitude, 2.0))))
                .Take(3).ToList();

            List<RobotMatchDto> data = new List<RobotMatchDto>();
            robotList.ForEach(item =>
            {
                RobotMatchDto match = new RobotMatchDto
                {
                    Status = item.AvailableStatus,
                    Distance = GetDistance(item.Longitude, item.Latitude, request.Longitude, request.Latitude, 2).ToString(),
                    RobotName = item.DeviceNumber + "-测量机器人",
                    Longitude = item.Longitude,
                    Latitude = item.Latitude,
                    Id = item.DeviceGuid
                };
                data.Add(match);
            });
            return new RobotScheduleDto
            {
                IsMatch = robotList != null && robotList.Count > 0,
                MatchingRobotList = data
            };
        }

        public RobotInfoDto GetRobotDetail(Guid id)
        {
            var robot = RobotInfoDao.GetById(id);
            if (robot == null)
            {
                throw new OperationException($"机器人不存在:{id}");
            }
            var data = Mapper.Map<RobotInfoDto>(robot);
            var user = SysUserRepository.GetById(robot.DeviceUserId);
            if (user != null)
                data.Phone = user.PhoneNumber;
            return data;
        }

        private double GetDistance(double lon1, double lat1, double lon2, double lat2, int digits)
        {
            var value = Math.Sqrt(Math.Abs(Math.Pow(lon1 - lon2, 2.0)) + Math.Abs(Math.Pow(lat1 - lat2, 2.0))) * 100;
            return Math.Round(value, digits);
        }
    }
}
